<?php
    namespace App\common;
	
	use Illuminate\Support\Facades\Redis;

    class cRedis implements iCache
	{
        public function __construct()
		{
            $this->m_o_reids = Redis::connection('default')->client();
        }
        public function get($key,$callback_get=null)
		{
            if($callback_get==null)
			{
                return $this->m_o_reids->get($key);
            }
			else
			{
                $callback_get($this->m_o_reids->get($key));
                return $this;
            }
        }
        public function set($key,$value)
		{
            $this->m_o_reids->set($key,$value);
            return $this;
        }
		public function get_raw_redis_object () 
		{
			return $this->m_o_reids;
		}
		public function list($key)
		{
			$p_this						= $this;return new class ($this,$key)
			{
				public function __construct($p_this,$key)
				{
					$this->m_key		= $key							;	# redis list key
					$this->m_p_this		= $p_this						;
					$this->m_o_reids	= $this->m_p_this->m_o_reids	;
					$this->m_debug		= false							;
				}
				public function set_enable_debug($debug=true)
				{
					$this->m_debug		= $debug;
					return $this;
				}
				public function push($value)
				{
					$key				= $this->m_key;$this->m_o_reids->lpush($key,$value);
					return $this;
				}
				public function pop($callback_list_pop=null)
				{
					$key				= $this->m_key;
					$v					= $this->m_o_reids->rpop($key) /* pop one value from redis list  by right  */;if($callback_list_pop==null)
					{
						return $v;
					}
					else
					{
						$callback_list_pop($v);
					}

					return $this;
				}
				public function length($callback_list_length=null)
				{
					$key				= $this->m_key;
					$v					= $this->m_o_reids->llen($key);if($callback_list_length==null)
					{
						return $v;
					}
					else
					{
						$callback_list_length ($v);
					}
					return $this;
				}
				public function for_each($callback_list_for_each)
				{
					$key				= $this->m_key;
					for(;;)
					{
						$list_length	= $this->length();if( $list_length > 0)
						{
							$this->pop		(
												function($v) use($callback_list_for_each,$list_length) 
												{
													$callback_list_for_each ($v/* pop one value from redis list  by right  */,$list_length /* current redis list length */);
												}
											);
						}
						else
						{
							break; 
						}
					}
				}
				private function debug_echo($s)
				{
					if($this->m_debug)
					{
						echo $s;

						# echo '\n';
						#
						#
						echo "\n";
					}
				}
				public function split_2_x($number,$on_ok=null,$on_error=null)
				{
					# number must over 1
					#
					#
					$number	= intval($number);if($number<=1)
					{
						$on_error==null?'':$on_error($this->m_key,$number);
						return $this;
					}			

					#
					#
					#
					$n_total_length	= $this->length()										;	# total length
					$n_piece_length	= floor($this->length()/$number)						;	# |-----------------+ 1 +-----------------+ 2 +-----------------+ 3 +-----------------+ 4 +-----------------+ N +-----------------|
					#
					#
					#
					#
					#																			  ^	                ^   ^	              ^   ^	                ^   ^	              ^   ^	                ^   ^	              ^        
					#																			  ^	                ^   ^	              ^   ^	                ^   ^	              ^   ^	                ^   ^	              ^        
					#																			  ^	                ^   ^	              ^   ^	                ^   ^	              ^   ^	                ^   ^	              ^        
					#																			  ^	                ^   ^	              ^   ^	                ^   ^	              ^   ^	                ^   ^	              ^        
					#																			  ^	                ^   ^	              ^   ^	                ^   ^	              ^   ^	                ^   ^	              ^        
					#																			  ^	                ^   ^	              ^   ^	                ^   ^	              ^   ^	                ^   ^	              ^        
					#																			  ^	                ^   ^	              ^   ^	                ^   ^	              ^   ^	                ^   ^	              ^        
					#																			  |                 |   |                 |   |                 |   |                 |   |                 |   |                 | 	
					#																			  |                 |	|                 |	  |                 |   |                 |   |                 |	|                 |
					#																			  |                 |	|                 |	  |                 |   |                 |   |                 |	|                 |
					#																			  |                 |	|                 |	  |                 |   |                 |   |                 |	|                 |
					#																			  |                 |	|                 |	  |                 |   |                 |   |                 |	|                 |
					#																			  |------> 0 <------|	|------> 1 <------|	  |------> 2 <------|   |------> 3 <------|   |------> 4 <------|	|------> N <------|
					#																								
					#																				
					#																					
					#																					
					#																					
					#			
					$this->debug_echo('the total number of list items	: '.$n_total_length		);
					$this->debug_echo('the length of a piece           : '.$n_piece_length		);

					# split
					#
					#
					$ar_key_list		= [];
					$pop_number			= 0;
					$raw_key			= $this->m_key;for($i=0;$i<$number;$i++)
					{
						# sub list key name
						#
						#
						$key_one		= $this->m_key.'.'.$i;
						$ar_key_list[]	= $key_one;
						
						# adjust sub list length
						#
						#
						if ( ($i+1) === $number /* equal last index */)
						{
							$pop_number	= ($n_total_length - $i * $n_piece_length);
						}
						else
						{
							$pop_number	= $n_piece_length;
						}

						#
						#
						#
						$this->debug_echo('redis sub list key name		: '. $key_one.' => '.$pop_number)		;
						$sub_redis_list = $this->m_p_this->list ($key_one)								; # generation a sub REDIS list
						for($ii=0;$ii<$pop_number;$ii++)
						{
							$this->pop	(
											function ($v_one_item) use($ii,$key_one,&$sub_redis_list)
											{
												# $this->debug_echo ($ii.' : '.$key_one.' => ['.$v_one_item.']');
												#
												#
												
												# lpush data to redis
												#
												#
												$sub_redis_list->push($v_one_item);												
											}
										);
						}
					}
					$on_ok==null?'':$on_ok($ar_key_list);
					return $this;
				}
			};
		}
    }
